<template>
  <div class="goods-main">
    <el-form label-width="150px" label-position="top">
      <el-card class="box-card">
        <template #header>
          <div class="card-header">
            <span>基本信息</span>
          </div>
        </template>
        <div>
          <el-form-item label="商品标题">
            <el-input v-model="source.goodsEditFrom.goodsName" show-word-limit :maxlength="60" />
          </el-form-item>

          <el-form-item label="商品图片和视频">
            <el-upload
              ref="commdityImgOrVideo"
              v-model:file-list="carousels"
              :before-upload="befaoreUploadCarouselsImg"
              action=""
              :http-request="handleHttpUpload"
              list-type="picture-card"
              :auto-upload="true"
              :multiple="true"
              :limit="8"
              :on-success="uploadCarouselSuccess"
              :on-exceed="handleCarouselExceed"
              :on-error="uploadError"
            >
              <el-icon>
                <Plus />
              </el-icon>
              <template #file="{ file }">
                <div class="w100 h100">
                  <video v-if="isMP4Format(file.url)" width="146" height="146" controls autoplay>
                    <source :src="file.url" type="video/mp4" />
                  </video>
                  <img v-else class="el-upload-list__item-thumbnail w100 h100" :src="file.url" alt="" />

                  <span class="el-upload-list__item-actions">
                    <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
                      <el-icon><zoom-in /></el-icon>
                    </span>
                    <span class="el-upload-list__item-delete" @click="handleCarouselImgsRemove(file)">
                      <el-icon>
                        <Delete />
                      </el-icon>
                    </span>
                  </span>
                </div>
              </template>
            </el-upload>
          </el-form-item>
          <div class="goods-upload-desc">
            <p>1.最少上传3个素材，最多上传8个素材，其中最多上传1个视频(mp4格式)，视频将默认展示在图片前。</p>
            <p>2.视频时长不超过60秒，视频大小不超过200M，单张图片需限制在10M以内。</p>
          </div>
        </div>
      </el-card>

      <el-card class="box-card mt10">
        <template #header>
          <div class="card-header">
            <span>商品属性</span>
          </div>
        </template>
        <div>
          <div class="goods-attribute">
            <div class="attribute-key">
              <span>属性:</span>
              <el-input class="attr-value" :readonly="true" v-model="source.goodsEditFrom.goodsAttr.attrName" />
            </div>
            <div class="attribute-value-row" :key="index" v-for="(item, index) of source.goodsEditFrom.goodsAttr.attrValue">
              <el-input class="attr-value" v-model="item.value" show-word-limit maxlength="10" />
              <el-upload
                class="attr-uploader"
                :http-request="handleHttpUpload"
                :on-success="
                  (response: Upload.ResFileInfo | undefined) => {
                    if (!response) return;
                    item.img = response.path;
                  }
                "
                action=""
                :show-file-list="false"
              >
                <img class="avatar" v-if="item.img" :src="item.img" />
                <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
              </el-upload>
              <el-button
                :icon="Delete"
                v-show="source.goodsEditFrom.goodsAttr.attrValue.length > 1"
                class="del-btn"
                @click="delGoodsAttrValue(index)"
              />
            </div>
          </div>
          <div class="add-row-btn">
            <span @click="addGoodsAttrValue">
              <CirclePlus style="width: 1.5em; height: 1.5em; margin-right: 8px"></CirclePlus>
              添加子属性
            </span>
          </div>
        </div>
      </el-card>

      <el-card class="box-card mt10">
        <template #header>
          <div class="card-header">
            <span>规格售价与库存</span>
          </div>
        </template>
        <div class="price_inventory">
          <div class="title">
            <p>会员价</p>
            <p>市场价</p>
            <p>库存</p>
          </div>
        </div>

        <div class="listItem" v-for="(item, index) of source.goodsEditFrom.goodsAttr.attrValue" :key="index">
          <div class="specs-info flx-center">
            <el-upload
              class="attr-uploader"
              :http-request="handleHttpUpload"
              :on-success="
                (response: Upload.ResFileInfo | undefined) => {
                  if (!response) return;
                  item.img = response.path;
                }
              "
              action=""
              :show-file-list="false"
            >
              <img class="avatar" v-if="item.img" :src="item.img" />
              <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
            </el-upload>

            <span class="sle ml10">{{ item.value }}</span>
          </div>

          <div class="price-info mt15">
            <el-input-number :min="1" :max="9999" :precision="2" class="mr5 ml5 w100" v-model="item.memberPrice" />
            <el-input-number :min="1" :max="9999" :precision="2" class="mr5 ml5 w100" v-model="item.marketPrice" />
            <el-input-number :min="0" :max="9999" :precision="0" class="mr5 ml5 w100" v-model="item.inventory" />
          </div>
        </div>
      </el-card>
      <el-card class="box-card mt10">
        <template #header>
          <div class="card-header">
            <span>商品详情与规格参数</span>
          </div>
        </template>
        <div class="goods-info-specs">
          <div class="goods-info-img">
            <div class="title mt15 mb15">
              <span>商品详情图片</span>
            </div>
            <div class="goods-upload-img">
              <el-upload
                ref="goodsInfoImg"
                v-model:file-list="goodsInfoImgs"
                :before-upload="befaoreUploadGoodsInfoImg"
                action=""
                :http-request="handleHttpUpload"
                list-type="picture-card"
                :auto-upload="true"
                :multiple="true"
                :limit="20"
                :on-success="uploadInfoImgSuccess"
                :on-exceed="handleInfoImgExceed"
                :on-error="uploadError"
              >
                <el-icon>
                  <Plus />
                </el-icon>
                <template #file="{ file }">
                  <div class="w100 h100">
                    <img class="el-upload-list__item-thumbnail w100 h100" :src="file.url" alt="" />
                    <span class="el-upload-list__item-actions">
                      <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
                        <el-icon><zoom-in /></el-icon>
                      </span>
                      <span class="el-upload-list__item-delete" @click="handleGoodsInfoImgsRemove(file)">
                        <el-icon>
                          <Delete />
                        </el-icon>
                      </span>
                    </span>
                  </div>
                </template>
              </el-upload>
            </div>

            <div class="goods-upload-desc">
              <p>1.最少上传3个素材，最多上传20个素材，</p>
              <p>2.单张图片需限制在10M以内。</p>
            </div>
          </div>
          <div class="goods-specs">
            <div class="title mt15 mb15">
              <span>规格参数</span>
            </div>

            <div class="specs-item" :key="index" v-for="(item, index) of source.goodsEditFrom.goodsSpecs">
              <el-input v-model="item.k" style="width: 30%" class="mr10" placeholder="规格名称" show-word-limit :maxlength="60" />
              <el-input v-model="item.v" style="width: 30%" class="mr10" placeholder="规格值" show-word-limit :maxlength="60" />
              <el-button :icon="Delete" class="del-btn" @click="delSpcesItem(index)" />
            </div>
            <div class="add-row-btn">
              <span @click="addGoodsSpecs">
                <CirclePlus style="width: 1.5em; height: 1.5em; margin-right: 8px"></CirclePlus>
                添加子属性
              </span>
            </div>
          </div>
        </div>
      </el-card>
    </el-form>

    <div class="bootm-menu">
      <el-button type="danger" :icon="ArrowLeftBold" @click="goBack">返回</el-button>
      <el-button type="primary" :icon="Select" @click="saveGoods()">保存</el-button>
    </div>

    <el-dialog v-model="source.dialog.visible" :title="source.dialog.title">
      <div class="dialogFileShow">
        <img v-if="!isMP4Format(source.dialog.fileUrl)" :src="source.dialog.fileUrl" />
        <video v-else controls autoplay>
          <source :src="source.dialog.fileUrl" type="video/mp4" />
        </video>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts" name="add-commodity">
import { onMounted, reactive, ref } from "vue";
import { UPLOAD_IMG_TYPE, UPLOAD_VIEDO_TYPE, UPLOAD_IMG_SIZE, UPLOAD_VIEDO_SIZE } from "@/config";
import { ElMessage, ElNotification } from "element-plus";
import { uploadImgApi, uploadVideoApi } from "@/api/modules/upload";
import type { UploadUserFile, UploadRequestOptions, UploadFile, ElUpload } from "element-plus";
import { Upload } from "@/api/interface/index";
import { isMP4Format } from "@/utils/is";
import { getFileName } from "@/utils";
import { Delete, CirclePlus, Select, ArrowLeftBold } from "@element-plus/icons-vue";
import { Goods } from "@/api/interface";
import { insertApi, getApi, updateApi } from "@/api/modules/goods";
import deepcopy from "deepcopy";
import { useRouter } from "vue-router";
const commdityImgOrVideo = ref<InstanceType<typeof ElUpload>>();
const goodsInfoImg = ref<InstanceType<typeof ElUpload>>();
const carousels = ref<UploadUserFile[]>([
  // //轮播素材 图片容器
  // {
  //   name: "28921843a4af4249be749099cf163057.mp4",
  //   url: "https://jvod.300hu.com/vod/product/fa90df8b-34ed-40e5-acd2-9eba1f48c29e/28921843a4af4249be749099cf163057.mp4"
  // },
  // {
  //   name: "693c690386099385.jpg",
  //   url: "https://img14.360buyimg.com/n0/jfs/t1/125292/19/40901/137451/64fdc6b3F9c1421dc/693c690386099385.jpg"
  // }
]);
//商品详情图片素材
const goodsInfoImgs = ref<UploadUserFile[]>([]);
const router = useRouter();
onMounted(() => {
  const id = router.currentRoute.value.query.id as string;
  if (id) {
    getApi(id).then(({ data }) => {
      source.goodsEditFrom = data;
      const carouselTemp = data.goodsCarousel.split(",");
      carouselTemp.forEach(v => {
        carousels.value.push({ name: getFileName(v), url: v });
      });
      const goodsImgTemp = data.goodsInfoImg.split(",");
      goodsImgTemp.forEach(v => {
        goodsInfoImgs.value.push({ name: getFileName(v), url: v });
      });
    });
  }
});

interface DialogInfo {
  visible: boolean;
  fileUrl: string;
  title: string;
}
const source = reactive({
  dialog: { visible: false, fileUrl: "", title: "展示素材" } as DialogInfo,
  goodsEditFrom: {
    goodsSpecs: [] as Array<Goods.GoodsSpecs>,
    goodsAttr: { attrName: "规格/净含量", attrValue: [{ value: "" }] }
  } as Goods.GoodsEditFrom
});
/** 移除 轮播图片 */
const handleCarouselImgsRemove = (uploadFile: UploadFile) => {
  commdityImgOrVideo.value?.handleRemove(uploadFile);
};
/** 移除 商品详情图片 */
const handleGoodsInfoImgsRemove = (uploadFile: UploadFile) => {
  goodsInfoImg.value?.handleRemove(uploadFile);
};
const handlePictureCardPreview = (file: UploadUserFile) => {
  source.dialog.fileUrl = file.url || "";
  if (source.dialog.fileUrl) {
    source.dialog.visible = true;
  }
};
const befaoreUploadCarouselsImg = (file: any): boolean => {
  if (!UPLOAD_IMG_TYPE.includes(file.type) && !UPLOAD_VIEDO_TYPE.includes(file.type)) {
    ElMessage.error("现支持的文件格式为:" + UPLOAD_IMG_TYPE.toString() + UPLOAD_VIEDO_TYPE.toString());

    return false;
  }
  if (UPLOAD_IMG_TYPE.includes(file.type) && file.size > UPLOAD_IMG_SIZE) {
    ElMessage.error("图片不能大于10MB");
    return false;
  }
  if (UPLOAD_VIEDO_TYPE.includes(file.type) && file.size > UPLOAD_VIEDO_SIZE) {
    ElMessage.error("视频不能大于200MB");
    return false;
  }
  return true;
};

const befaoreUploadGoodsInfoImg = (file: any): boolean => {
  if (!UPLOAD_IMG_TYPE.includes(file.type)) {
    ElMessage.error("现支持的文件格式为:" + UPLOAD_IMG_TYPE.toString());
    return false;
  }
  if (UPLOAD_IMG_TYPE.includes(file.type) && file.size > UPLOAD_IMG_SIZE) {
    ElMessage.error("图片不能大于10MB");
    return false;
  }
  return true;
};
function intallFormData(file: any, paramKey: string): FormData {
  const formData = new FormData();
  formData.append(paramKey, file);
  return formData;
}
//自定义文件上传
const handleHttpUpload = async (options: UploadRequestOptions) => {
  try {
    if (UPLOAD_IMG_TYPE.includes(options.file.type)) {
      const { data } = await uploadImgApi(intallFormData(options.file, "img"));
      options.onSuccess(data);
    } else {
      const { data } = await uploadVideoApi(intallFormData(options.file, "video"));
      options.onSuccess(data);
    }
  } catch (error) {
    options.onError(error as any);
  }
};
//自定义文件上传成功后处理
const uploadCarouselSuccess = (response: Upload.ResFileInfo | undefined, uploadFile: UploadFile) => {
  if (!response) return;
  uploadFile.url = response.path;
  uploadFile.name = response.name;
  if (isMP4Format(response.path) && isMP4Format(carousels.value[0].url) && response.path !== carousels.value[0].url) {
    carousels.value[0].url = response.path;
    carousels.value[0].name = response.name;
    commdityImgOrVideo.value?.handleRemove(uploadFile);
  } else if (isMP4Format(response.path)) {
    commdityImgOrVideo.value?.handleRemove(uploadFile);
    carousels.value.unshift({ name: response.name, url: response.path });
  }
};

/**
 * 上传商品详情图片成功回调
 */

const uploadInfoImgSuccess = (response: Upload.ResFileInfo | undefined, uploadFile: UploadFile) => {
  if (!response) return;
  uploadFile.url = response.path;
  uploadFile.name = response.name;
};
/**
 * 上传商品详情图片超出限制
 */

const handleInfoImgExceed = () => {
  ElNotification({
    title: "温馨提示",
    message: `当前最多只能上传20个素材，请移除后上传！`,
    type: "warning"
  });
};
/**
 * @description 图片上传错误
 * */
const uploadError = () => {
  ElNotification({
    title: "温馨提示",
    message: "图片或视频上传失败，请您重新上传！",
    type: "error"
  });
};

/**
 * @description 文件数超出
 * */
const handleCarouselExceed = () => {
  ElNotification({
    title: "温馨提示",
    message: `当前最多只能上传8个素材，请移除后上传！`,
    type: "warning"
  });
};

/**
 * 删除商品属性
 */
const delGoodsAttrValue = (index: number) => {
  if (source.goodsEditFrom.goodsAttr.attrValue.length > 1) source.goodsEditFrom.goodsAttr.attrValue.splice(index, 1);
};

/**
 * 添加商品属性
 */

const addGoodsAttrValue = () => {
  source.goodsEditFrom.goodsAttr.attrValue.push({} as Goods.AttrInfo);
};

/**
 * 添加商品规格参数
 */

const addGoodsSpecs = () => {
  source.goodsEditFrom.goodsSpecs.push({} as Goods.GoodsSpecs);
};

/**
 * 删除规格参数
 */

const delSpcesItem = (index: number) => {
  source.goodsEditFrom.goodsSpecs.splice(index, 1);
};

/** 保存商品信息 */
const saveGoods = () => {
  //拷贝数据
  const param = deepcopy(source.goodsEditFrom) as Goods.GoodsEditFrom;
  if (!carousels.value || carousels.value.length < 3) {
    ElMessage.error("请上传商品图片或视频最少3个素材");
    return;
  }
  //给轮播赋值
  param.goodsCarousel = carousels.value
    .map(v => {
      return v.url;
    })
    .toString();

  //给商品详情图片赋值

  if (!goodsInfoImgs.value || goodsInfoImgs.value.length < 3) {
    ElMessage.error("请上传详情图片最少3个素材");
    return;
  }
  param.goodsInfoImg = goodsInfoImgs.value
    .map(v => {
      return v.url;
    })
    .toString();

  if (param.id) {
    updateApi(param).then(() => {
      ElNotification({
        title: "温馨提示",
        message: `商品编辑成功！`,
        type: "success"
      });
      goBack();
    });
  } else {
    insertApi(param).then(() => {
      ElNotification({
        title: "温馨提示",
        message: `商品发布成功！`,
        type: "success"
      });
      goBack();
    });
  }
};

const goBack = () => {
  router.push("/goods_list");
};
</script>

<style scoped lang="scss">
.goods-upload-desc {
  color: rgba(0, 0, 0, 0.3);
  font-size: 14px;
}

.attribute-key {
  display: flex;
  align-items: center;
  span {
    display: inline-block;
    margin-right: 1rem;
    width: 3rem;
    color: #000;
    font-family: PingFang SC;
    font-size: 16px;
    font-weight: 400;
  }
}
.attr-value {
  width: 50%;
}
.attribute-value-row {
  margin-top: 10px;
  margin-left: 4rem;
  display: flex;
  align-items: center;
}
.del-btn {
  border: 1px dashed var(--el-border-color);
  width: 40px;
  height: 40px;
  margin-left: 10px;
}
.attr-uploader {
  width: 40px;
  height: 40px;
  margin-left: 10px;
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
  display: flex;
  align-items: center;
  justify-content: center;
  .avatar {
    width: 40px;
    height: 40px;
  }
  :deep(.el-upload) {
    width: 100%;
    height: 100%;
  }
}
.add-row-btn {
  span {
    color: #576b95;
    display: flex;
    font-family: PingFangSC-Regular;
    font-size: 14px;
    font-weight: 400;
    height: 50px;
    padding: 16px 16px 16px 64px;
    cursor: pointer;
  }
}
.price_inventory {
  .title {
    border-bottom: 1px solid #f6f7f8;
    display: flex;
    padding: 15px 0;
    p {
      color: #000;
      font-family: PingFangSC-Regular;
      font-size: 16px;
      font-weight: 400;
      opacity: 0.9;
      padding-left: 16px;
      width: 33.33%;
    }
  }
}
.listItem {
  margin-top: 15px;
  .specs-info {
    justify-content: flex-start;
    span {
      color: #000;
      display: inline-block;
      font-family: PingFangSC-Regular;
      font-size: 14px;
      font-weight: 400;
      height: 40px;
      line-height: 40px;
    }
  }
  .price-info {
    display: flex;
  }
}
.dialogFileShow {
  width: 100%;
  height: 500px;

  img {
    width: 100%;
    height: 100%;
  }
  video {
    width: 100%;
    height: 500px;
  }
}
.goods-info-specs {
  .title {
    span {
      font-size: 18px;
      line-height: 28px;
    }
  }
}
.specs-item {
  margin-top: 10px;
  display: flex;
  align-items: center;
}

.goods-main {
  position: relative;
}
.bootm-menu {
  background-color: #fff;
  padding: 20px;
  text-align: right;
  box-sizing: border-box;
  bottom: 0px;
  width: 100%;
  z-index: 998;
}
</style>
